package com.example.petcare.interceptors;

import com.example.petcare.exception.NoJWTException;
import com.example.petcare.utils.JwtUtil;
import com.example.petcare.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.Map;

@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取请求头中的token
        String token = request.getHeader("Authorization");

        // 验证token是否合法
        try {
            // 从redis中获取相同的token
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();// 获取操作对象
            String redisToken = operations.get(token);// 这里会从redis中尝试获取值相同的token,找到就赋值，否则就为null

            if(redisToken == null){
                // token已经失效了
                throw new NoJWTException("JWT令牌已经失效，请重新登录");
            }

            // 解析token
            Map<String, Object> claims = JwtUtil.parseToken(token);

            // 获取用户角色
            String role = JwtUtil.getRoleFromToken(token);
            log.info("这是登录拦截器所输出的身份: {}", role);

            // 存储角色信息
            ThreadLocalUtil.setRole(role);

            // 把业务数据存储到ThreadLocal中
            ThreadLocalUtil.set(claims);

            // 获取请求的 URI
            String requestURI = request.getRequestURI();
            // 角色权限控制
            if (isAuthorized(role, requestURI)) {
                return true; // 允许访问
            }

            // 不允许访问，返回403
            response.setStatus(403);
            return false;

        } catch (Exception e) {
            // http状态码401,表示未授权
            response.setStatus(401);
            return false; // 不放行
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清除ThreadLocal中的数据
        ThreadLocalUtil.remove();
    }


    // 角色权限检查逻辑
    private boolean isAuthorized(String role, String requestURI) {
        if ("admin".equals(role)) {
            return requestURI.startsWith("/admin") || requestURI.startsWith("/provider"); // admin可以访问以/admin和/provider开头的资源
        } else if ("provider".equals(role)) {
            return requestURI.startsWith("/provider"); // provider只能访问以/provider开头的资源
        } else if ("user".equals(role)) {
            return requestURI.startsWith("/user"); // user只能访问以/user开头的资源
        }
        return false; // 其他角色不允许访问
    }
}